TITL DAI FIRMWARE DD1A-DEB4 V1.0 Rev.1 ORG :DD1A * * * ******************* * INPUT TEXT LINE * ******************* * * Part of 'restart interpreter' (C853). * Scans keyboard and reads in a line on the current * screen line, up until car.ret. First prints * car.ret and a prompt ('*'). * The routine can be aborted on car.ret or Break * only. * * Entry: A: Contains prompt. * Exit: CY=1: Break pressed. * CY=0: HL: Address 1st character on line. * C=1: Offset 1st significant character. * ABDEHL preserved. * INPL0 PUSH PSW CALL :DD55 Cursor to column 0 POP PSW Get prompt INPLN STC CY=1 PUSH PSW PUSH H Save cursor coord 1st char IPL10 CALL :DD6A Print prompt LXI H,:02B9 MVI M,:00 Enable complete keyb.scan IPL20 CALL :D6BE Get keyb. input JC :DD49 Ignore line if Break pressed JZ :DD2A Wait for input CPI :20 Printable character? JNC :DD22 Print it and get next one CPI :08 Backspace JZ :DD22 Print it; get next char CPI :0D Car.ret? JNZ :DD2A Get next char if not REM * Exit on car.ret: REM DCR M Set KBRFL for BREAK only MVI C,:01 EXIT1 POP H Get cursor coord 1st char POP PSW Get prompt CMC CY=0 RET REM * Exit on Break: REM IPL30 DCR M Set KBRFL for BREAK only MVI A,:21 CALL :DD60 Print '!' CALL :DD5E Print car.ret POP H POP PSW Get prompt, CY=1 RET * ********************** * CURSOR TO COLUMN 0 * ********************** * * The X-coordinate of the cursor is checked. * If not 0, a car.ret is printed. * * Entry: None. * Exit: AF corrupted. BCDEHL preserved. * COL0 PUSH D PUSH H RST 5 Get cursor pos (HL) and size DATA :0C char.screen (DE) MOV A,L X-coord cursor in A POP H POP D ORA A RZ Abort if cursor in Col.0 CRLF MVI A,:0D Else: print CR * * GENERAL OUTPUT ROUTINE: * * Outputs a character in a direction depending * on OTSW (#0131). * * Entry: A: Character to be transmitted. * Exit: AF corrupted. * *SCCHR OUTC PUSH PSW Preserve char LDA :0131 CPI :02 Check output direction JNC :DD70 If to edit buf/DOUTC REM * To screen/RS232 - OTSW=0/1: REM POP PSW Get char COUTC RST 5 Character to screen DATA :03 CNC :D642 Output to RS232 if reqd RET REM * To DOUTC - OTSW=3: REM OTC10 NOP JNZ :D74C Character to DOUTC REM * To editbuffer - OTSW=2: REM POP PSW Get char OTBIN PUSH PSW PUSH H PUSH D LHLD :00A4 Get edit input pointer MOV M,A Byte in edit buffer INX H SHLD :00A4 Update edit input pointer XCHG in DE LHLD :00A6 Get end edit buffer CALL :DE14 Calculate free buffer space JC :DD8E If edit buffer full POP D POP H OTC99 POP PSW RET REM * If edit buffer full: REM OTC20 CALL :DECA Heap back to right size JMP :DA10 Run error 'OUT OF MEMORY' * ******************* * OUTPUT TO RS232 * ******************* * * Transmits a character to the RS232 interface via * the TICC if the interface is ready for it. * In case of a car.ret, also a line feed is send. * * Entry: A: Character to be transmitted. * Exit: ABCDEHL preserved, F corrupted. * OUTSE PUSH PSW Preserve char OTS10 LDA :FD00 ANI :08 Check peripheral ready JZ :DD95 Wait untill ready OTS20 LDA :FFF3 ANI :10 Check TICC buffer empty JZ :DD9D Wait untill empty POP PSW Get char STA :FFF6 Load serial output buffer CPI :0D Carriage return? RNZ Ready if not REM * If car.ret: REM PUSH PSW MVI A,:0A CALL :DD94 Send line feed too POP PSW RET * ******************** * INPUT FROM RS232 * ******************** * * Gets inputs from RS232 via TICC. Only 7-bit * Ascii-code is accepted. * * Entry: No conditions. * Exit: A: Character received (0 if nothing). * BCDEHL preserved. * *CINC INSER LDA :FFF3 ANI :08 Check if something received RZ Abort if no reception LDA :FFF0 Received char in A ANI :7F Mask bit 7 RET * ********************************** * RS232 FRAME ERROR - (not used) * ********************************** * * Break test for serial input line. * BRSER LDA :FFF3 RAR RNC Abort if no break BRS10 LDA :FFF3 If break: check again RAR JC :DDC5 Wait until end of break LDA :FFF0 Load received character CMC Set CY=1 RET * * * =========================== *** ENCODING SERVICE ROUTINES *** * =========================== * * * The following routines are used both in 'main' * and 'decode' modules. * ************************************************ * GET CHARACTER FROM LINE, NEGLECT TAB + SPACE * ************************************************ * * Entry: C: Position on current line. * Exit: Character in A; tab and space neglected. * C: Points to next character. * BDEHL preserved. * IGNBR INR C Pnts to next char IGNB CALL :DDE0 Get char from line CPI :20 Space? JZ :DDD1 Then get next char CPI :09 Tab? JZ :DDD1 Then get next char RET * *************************** * GET CHARACTER TO ENCODE * *************************** * * Returns a character from some position on the * current line. The source is determined by EFSW. * * Entry: C: Position on current line (max. 219). * Exit: EFSW=0 - Keyboard: Char on line pos in A. * EFSW>=2 - Edit buf: Char on EFEPT + line * pos in A. * EFSW=1 - String: Idem. If COUNT=line pos * then char is car.ret. * F corrupted, BCDEHL preserved. * EFETCH LDA :0135 CPI :01 Check input direction JC :DDFF If from keyb/RS232 JNZ :DDF4 If from edit buffer REM * If from string: REM LDA :0134 If string: Get COUNT CMP C COUNT=pos.on curr.line? MVI A,:0D Then char is car.ret JZ :DDFE And abort REM * Entry if from edit buffer: REM EFC10 PUSH H LHLD :0132 Get EFEPT MOV A,C CALL :DE30 Add curr.line pos to EFEPT MOV A,M Get character POP H EFC20 RET REM * If from screen: REM EFC30 RST 5 Get character from line DATA :15 RET * * * ================================== *** SINGLE AND DOUBLE BYTE UTILITIES *** * ================================== * * ********************************* * CHECK IF UPPER CASE CHARACTER * ********************************* * * Entry: A: Character to be checked. * Exit: CY=0: Not upper case. * CY=1: Upper case. * ABCDEHL preserved, F corrupted. * ALPHA CPI :41 Lowest upper case char CMC RNC CPI :5B First lower case char RET * ********************************************** * CHECK IF CHARACTER IS NUMBER OR UPPER CASE * ********************************************** * * Entry: A: Character to be checked. * Exit: CY=0: Not number, not upper case. * CY=1: Number or upper case. * ABCDEHL preserved. F corrupted. * ALNUM CALL :DE02 Check if upper case RC NUMER CPI :30 Lowest number CMC RNC CPI :3A No number anymore RET * ********************* * COMPARE HL AND DE * ********************* * * Compares HL with DE (HL-DE). * * Exit: DE=HL: Z=1, CY=0. * DEHL: Z=0, CY=1. * BCDEHL preserved, AF corrupted. * COMP MOV A,H CMP D RNZ MOV A,L CMP E RET * ***************************** * CALCULATE LENGTH OF BLOCK * ***************************** * * Sets HL=HL-DE. * * Entry: Startaddress in DE, 1st address after * block in HL. * Exit: Length in HL, startaddress in DE. * If DE>HL, length in 2-complement. * ABCDE preserved, F as in COMP. * SUBDE PUSH B PUSH PSW MOV A,L SUB E Calc. difference lowest byte MOV L,A MOV A,H SBB D Calc. diff. highest byte MOV H,A POP B MOV A,B POP B RET * ****************************** * DOUBLE BYTE TWO COMPLEMENT * ****************************** * * Sets HL=-HL. * * Entry: Double byte to be converted in HL. * Exit: Two complement in HL. ABCDEF preserved. * CMPHL PUSH PSW MOV A,H CMA Complement H MOV H,A MOV A,L CMA Complement L MOV L,A INX H Add 1 POP PSW RET * ************************** * ADD OFF-SET TO ADDRESS * ************************** * * Adds a given offset to a base address (HL=HL+A). * * Entry: Base in HL, offset in A. * Exit: HL=HL+A. ABCDE preserved, F corrupted. * DADA PUSH PSW ADD L MOV L,A L=L+A MOV A,H ACI :00 Add carry if overflow MOV H,A POP PSW RET * ********************************** * CALCULATE ADDRESS AFTER STRING * ********************************** * * Sets HL=HL+M+1. * * Entry: HL points to 1st byte of string (length * byte). * Exit: HL points to first byte after string. * AFBCDE preserved. * DADM PUSH PSW MOV A,M Get length of string INX H HL: addr. 1st char. byte CALL :DE30 Calc addr after string POP PSW RET * ***************** * DELAY ROUTINE * ***************** * * Runs a fixed delay loop of 665 msec. If * interrupts are enabled, the delay will be * approx. 750 msec. * HL is loaded with FFFF, and then decremented. * * Exit: ABCDEHL preserved; F corrupted. * DELAY PUSH H PUSH D LXI H,:FFFF Init. delay value MOV D,H MOV E,L DLY10 DAD D JC :DE48 Repeat if not ready POP D POP H RET * *********************** * DATA BLOCK TRANSFER * *********************** * * Moves a block of data starting at (DE) and * ending at (HL)-1 to (BC). * * Entry: DE: Startaddr. source bank. * BC: Startaddr. destination bank. * HL: Points after end source bank. * Exit: AF preserved, BCDEHL corrupted. * MOVE PUSH PSW PUSH H CALL :DE1A Calc. length source bank MOV A,C SUB E MOV A,B SBB D JC :DE6C If destination addr. is REM lower than source addr. REM * Destination address > source address: REM MOV D,H MOV E,L Save length in DE DAD B Highest dest.addr. in HL POP B MOV10 MOV A,D Check if ready ORA E JZ :DE7A Then abort DCX D DCX H DCX B LDAX B Get byte to be transferred MOV M,A Transfer it JMP :DE5F Next one REM * Destination address < source address: REM MOV20 MOV A,H ORA L JZ :DE79 Abort if ready DCX H LDAX D Get byte to be transferred STAX B Transfer it INX D INX B JMP :DE6C Next byte REM * If ready: REM MOV30 POP H MOV40 POP PSW RET * ********************************* * FILL BANK WITH IDENTICAL DATA * ********************************* * * Fills an area of memory with a constant. * * Entry: DE: Startaddr. of bank. * HL: Points after bank. * A: Data to be loaded into bank. * Exit: DE: Points after bank. * BCHL preserved, AF corrupted. * FILL PUSH B MOV B,A Save data in B FIL10 CALL :DE14 Check if bank full JZ :DE8D Abort if ready JC :DE8D Abort if DE>HL MOV A,B Get data STAX D and store it INX D JMP :DE7E Next addr. FIL20 POP B RET * ******************** * MULTIPLY HL BY A * ******************** * * Multiplies a 16-bit value by a 8-bit value. * * Entry: HL: 16-bit value. * A: 8-bit value. * Exit: CY=0: Result in HL. * CY=1: Overflow. * ABCDE preserved. * HLMUL STC PUSH PSW PUSH D XCHG LXI H,:0000 Init. result HLM10 ORA A RAR Next bit of multiplier JNC :DE9F Jump if bit is 0 DAD D Add 1* HL if bit is 1 JC :DEAD Abort if overflow HLM20 ORA A JZ :DEB1 Abort if ready XCHG DAD H Multiply *2 XCHG JNC :DE96 Again if no overflow NOP NOP NOP NOP HLM90 NOP POP D POP PSW Error exit if overflow RET HLM99 POP D POP PSW CMC No error exit RET * * * UNL CINC EQU INSER SCCHR EQU OUTC LST END